import 'package:intl/intl.dart';
import 'package:mybase/base/tool/empty/FFEmpty.dart';
import 'package:mybase/base/tool/extension/FFStringExt.dart';
import 'package:mybase/base/tool/pprint/FFLog.dart';

class FFTime {
  ///mark-当前时间

  ///当前时间秒数
  static int nowSecond() {
    return dateToTimestampSecond(DateTime.now());
  }

  ///当前时间毫秒数
  static int nowMillSecond() {
    return dateToTimestampMill(DateTime.now());
  }

  ///当前时间DateTime
  static DateTime now() {
    return DateTime.now();
  }

  ///mark-时间比较

  ///两个DateTime 是否在同一天
  static bool dateSameDay(DateTime date1, DateTime date2) {
    bool same = false;
    if (date1.year == date2.year && date1.month == date2.month && date1.day == date2.day) {
      same = true;
    }
    return same;
  }

  ///两个时间戳 秒 是否在同一天
  static bool timeStampIsSameDay(int second1, int second2) {
    DateTime date1 = secondToDate(second1);
    DateTime date2 = secondToDate(second2);

    return dateSameDay(date1, date2);
  }

  ///返回值
  /// > 0:  date1 时间线在后几天，
  /// < 0:  date1 时间线在前几天，
  /// = 0： 同一天
  ///
  ///比较两个DateTime，相差多少天
  static int dateDiff(DateTime date1, DateTime date2) {
    Duration difference = date1.difference(date2);
    return difference.inDays;
  }

  ///返回值
  /// > 0:  second1 时间线在后几天，
  /// < 0:  second1 时间线在前几天，
  /// = 0： 同一天
  ///
  ///比较两个second，相差多少天
  static int dateDiffBySecond(int second1, int second2) {
    return dateDiff(secondToDate(second1), secondToDate(second2));
  }

  ///mark-转换操作

  ///subtract：true：减，false：加
  ///DateTime 加-减 Duration
  static DateTime dateByDate(DateTime date, Duration duration, {bool? subtract = true}) {
    if (subtract == true) {
      return date.subtract(duration);
    }

    return date.add(duration);
  }

  ///DateTime 转 时间戳 毫秒
  static int dateToTimestampMill(DateTime date) {
    return date.millisecondsSinceEpoch;
  }

  ///DateTime转 时间戳 秒
  static int dateToTimestampSecond(DateTime date) {
    return date.millisecondsSinceEpoch ~/ 1000;
  }

  ///毫秒 转 DateTime
  static DateTime millToDate(int milliseconds) {
    return DateTime.fromMillisecondsSinceEpoch(milliseconds);
  }

  ///秒 转 DateTime
  static DateTime secondToDate(int second) {
    return DateTime.fromMillisecondsSinceEpoch(second * 1000);
  }

  ///日期字符串 转 DateTime
  static DateTime? strDateToDate(String strDate) {
    try {
      return DateTime.parse(strDate);
    } catch (e) {
      FFLog.error("解析出错 e = ${e.toString()}");
    }
    return null;
  }

  ///mark-返回String 格式化
  ///参数DateTime
  static String dateFormat(DateTime? date, {String format = "yyyy-MM-dd HH:mm:ss"}) {
    if (date == null) return "";
    return DateFormat(format).format(date);
  }

  ///参数second
  static String dateFormatBySeconds(int? second, {String format = "yyyy-MM-dd HH:mm:ss"}) {
    if (second == null) return "";
    return DateFormat(format).format(secondToDate(second));
  }

  ///参数mill
  static String dateFormatByMill(int? mill, {String format = "yyyy-MM-dd HH:mm:ss.SSS"}) {
    if (mill == null || mill <= 0) return "";
    return DateFormat(format).format(millToDate(mill));
  }

  ///将second转成xx:xx:xx
  static String formatSecondsToTime(int seconds, {
    bool alwaysShowHour = false,
  }) {
    if (seconds <= 0) {
      if (alwaysShowHour) {
        return "00:00:00";
      }

      return "00:00";
    }

    int hours = (seconds ~/ 3600);
    int minutes = (seconds ~/ 60) % 60;
    int remainingSeconds = seconds % 60;

    String hoursStr = hours.toString().padLeft(2, '0');
    String minutesStr = minutes.toString().padLeft(2, '0');
    String secondsStr = remainingSeconds.toString().padLeft(2, '0');

    if (hours > 0) {
      return "$hoursStr:$minutesStr:$secondsStr";
    } else {
      if (alwaysShowHour) {
        return "00:$minutesStr:$secondsStr";
      }

      return "$minutesStr:$secondsStr";
    }
  }

  ///参数duration转成xx:xx:xx
  static String formatDuration(Duration? duration) {
    if (duration == null) return "";

    String twoDigits(int n) {
      if (n >= 10) return "$n";
      return "0$n";
    }

    String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60));
    String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60));
    String twoDigitHours = twoDigits(duration.inHours);

    if (duration.inHours > 0) {
      return "$twoDigitHours:$twoDigitMinutes:$twoDigitSeconds";
    } else {
      return "$twoDigitMinutes:$twoDigitSeconds";
    }
  }

  /// 将毫秒数转成xx:xx:xx.xxxxxx
  static String formatMillisecondsToTime(int milliseconds) {
    // 计算小时、分钟、秒和毫秒
    int hours = milliseconds ~/ (60 * 60 * 1000);
    int minutes = (milliseconds % (60 * 60 * 1000)) ~/ (60 * 1000);
    int seconds = (milliseconds % (60 * 1000)) ~/ 1000;
    int microSeconds = milliseconds % 1000;

    // 格式化为字符串
    String formattedHours = hours.toString().padLeft(2, '0');
    String formattedMinutes = minutes.toString().padLeft(2, '0');
    String formattedSeconds = seconds.toString().padLeft(2, '0');
    String formattedMicroSeconds = microSeconds.toString().padRight(6, '0');

    return '$formattedHours:$formattedMinutes:$formattedSeconds.$formattedMicroSeconds';
  }

  ///mark-其他未归类
  ///毫秒转分钟(带小数)
  static double millToMin(int mill) {
    int second = mill ~/ 1000;
    return second / 60;
  }

  ///毫秒转分钟(带小数)
  static double millToMinStr(String? mill) {
    if (FFEmpty.stringIsEmpty(mill)) {
      return 0.0;
    }

    int second = mill.toINT() ~/ 1000;
    return second / 60;
  }

  /// 秒数转成实体类
  static FFTimeEntity timeEntity(int seconds) {
    int hours = seconds ~/ 3600;
    int remainingSeconds = seconds % 3600;
    int minutes = remainingSeconds ~/ 60;
    int remainingSecondsFinal = remainingSeconds % 60;

    return FFTimeEntity(
      h: hours,
      m: minutes,
      s: remainingSecondsFinal,
    );
  }


  ///mark-特殊的用法
  /// 今天最后的时间点
  static DateTime todayEndDate() {
    DateTime todayDate = DateTime.now();
    //加上一天，再减去尾巴
    DateTime todayEndDate = todayDate.add(const Duration(days: 1)).subtract(Duration(
      hours: todayDate.hour,
      minutes: todayDate.minute,
      seconds: todayDate.second + 1,
      milliseconds: todayDate.millisecond,
      microseconds: todayDate.microsecond,
    ));

    return todayEndDate;
  }

  /// 今天开始的时间点
  static DateTime todayBeginDate() {
    DateTime todayDate = DateTime.now();
    //减去尾巴
    DateTime todayEndDate = todayDate.subtract(Duration(
      hours: todayDate.hour,
      minutes: todayDate.minute,
      seconds: todayDate.second,
      milliseconds: todayDate.millisecond,
      microseconds: todayDate.microsecond,
    ));

    return todayEndDate;
  }

  /// 指定日期开始的时间点
  static DateTime todayBeginDateByDate(DateTime date) {
    //减去尾巴
    DateTime todayEndDate = date.subtract(Duration(
      hours: date.hour,
      minutes: date.minute,
      seconds: date.second,
      milliseconds: date.millisecond,
      microseconds: date.microsecond,
    ));

    return todayEndDate;
  }

  /// 指定日期的最后的时间点
  static DateTime todayEndDateByDate(DateTime date) {
    //加上一天，再减去尾巴
    DateTime todayEndDate = date.add(const Duration(days: 1)).subtract(Duration(
      hours: date.hour,
      minutes: date.minute,
      seconds: date.second + 1,
      milliseconds: date.millisecond,
      microseconds: date.microsecond,
    ));

    return todayEndDate;
  }

  /// 指定日期所在自然周的星期一的开始的时间点
  static DateTime weekBeginByDate(DateTime date) {
    int dayOfWeek = date.weekday;
    DateTime week1 = date.subtract(Duration(days: dayOfWeek - 1));
    return todayBeginDateByDate(week1);
  }

  /// 指定日期所在自然周的星期日的开始的时间点
  static DateTime weekEndByDate(DateTime date) {
    int dayOfWeek = date.weekday;
    DateTime week1 = date.add(Duration(days: 7 - dayOfWeek));
    return todayBeginDateByDate(week1);
  }

  /// 指定日期所在自然月的第一天的开始的时间点
  static DateTime monthBeginByDate(DateTime date) {
    DateTime monthBegin = DateTime(date.year, date.month, 1);
    return monthBegin;
  }

  /// 指定日期所在自然月的最后一天的最后的时间点
  static DateTime monthEndByDate(DateTime date) {
    DateTime monthBegin = DateTime(date.year, date.month + 1, 0, 23, 59, 59);
    return monthBegin;
  }

  /// 指定日期所在年的第一天的开始的时间点
  static DateTime yearBeginByDate(DateTime date) {
    DateTime monthBegin = DateTime(date.year, 1, 1);
    return monthBegin;
  }

  /// 指定日期所在年的最后一天的最后的时间点
  static DateTime yearEndByDate(DateTime date) {
    DateTime yearEnd = DateTime(date.year + 1, 1, 1).subtract(const Duration(days: 1));
    return todayEndDateByDate(yearEnd);
  }
}

class FFTimeEntity {
  int h;
  int m;
  int s;

  FFTimeEntity({
    this.h = 0,
    this.m = 0,
    this.s = 0,
  });

  /// 有效的对象
  bool more0() {
    return h > 0 || m > 0 || s > 0;
  }

  String toH() {
    if (h < 10) {
      return "0$h";
    }
    return h.toString();
  }

  String toM() {
    if (m < 10) {
      return "0$m";
    }
    return m.toString();
  }

  String toS() {
    if (s < 10) {
      return "0$s";
    }
    return s.toString();
  }
}
